概述
在本文的前半部分,我們介紹了在 Unreal Engine (UE) 中進行記憶體優化的有用命令和工具。後半部分將解釋如何使用這些命令和工具來優化 UE 中的記憶體。
提供了大量的參考文章和視頻,將它們與本文結合,將加深你的理解。
環境
- Unreal Engine 5.4
 
主要內容
記憶體優化的目的
- 性能提升
高效的記憶體管理能提高幀率和整體遊戲性能。 - 解決記憶體不足導致的崩潰
 - 縮短載入時間
優化的材質和資源能縮短載入時間。 
有用的 UE 記憶體管理命令和工具
stat memory
- 命令: 
stat memory
顯示按類型分類的當前記憶體使用情況。 

Memreport
- 命令: 
memreport -full
將記憶體報告保存為轉儲文件。 - 命令: 
memreport -log
在日誌中顯示記憶體報告。 
Memreport 參考資料:
Qiita: 使用 Memreport 調查記憶體洩漏原因 (ja)
Memreport 範例
- 
顯示總記憶體使用情況
- 在轉儲文件中搜尋 "Physical Memory" 來找到此資訊。

 
 - 在轉儲文件中搜尋 "Physical Memory" 來找到此資訊。
 - 
列出按記憶體使用量排序的材質 (降序)
- 在轉儲文件中搜尋 "listtextures" 來查看此數據。

 
 - 在轉儲文件中搜尋 "listtextures" 來查看此數據。
 
物件列表命令
- 命令: 
obj list
列出當前存在的物件。 - 命令: 
obj list name=
按名稱搜尋物件。 - 命令: 
obj refs name=
顯示按名稱查找物件的參考。 
物件列表參考文章:
物件列表如下圖所示

垃圾回收 (GC) 命令
- 命令: 
obj gc
執行一次垃圾回收。 - 命令: 
gc.ForceCollectGarbageEveryFrame 1
強制每幀進行垃圾回收。 - 命令: 
gc.ForceCollectGarbageEveryFrame 0
停止每幀強制垃圾回收。 
通過垃圾回收 (GC) 可以釋放資源或檢查參考。
每幀強制垃圾回收可能會導致遊戲運行緩慢,因此建議僅在調查目的下使用。
GC 參考資料:
什麼是 GC?: 官方文檔: Unreal Engine 中的物件處理
低級記憶體追蹤器 (LLM)
- 命令: 
stat llm
使用低級記憶體追蹤器追蹤記憶體使用情況。 
更多詳情,請參考以下參考資料。
LLM 參考資料:
參考查看器 (Reference Viewer)
這個工具顯示了被其他資源參考或參考其他資源的資源圖。
你可以通過右鍵單擊 UE 中的資源並選擇 "Reference Viewer" 來使用它。
當不應該加載的資源意外加載時,這對於調查非常有用。

尺寸地圖 (Size Map)
右鍵單擊 UE 中的資源 -> "Size Map" -> 在右上角選擇 "Memory"。
顯示所有參考資源的總記憶體使用情況。
尺寸地圖參考:

記憶體洞察 (Memory Insight)
- 用於分析隨時間變化的記憶體分配和釋放。 範例: 時間 A -> 時間 B 記憶體分配 123.456MB
 
記憶體洞察參考:
Qiita: 使用 UE4 記憶體洞察進行記憶體追蹤 (ja)
記憶體洞察範例,調查記憶體洩漏視頻 (34:38): Maximizing Your Game's Performance in Unreal Engine | Unreal Fest 2022

記憶體調查和優化方法
記憶體優化流程通常遵循以下步驟:

識別記憶體問題
查找崩潰日誌或記憶體警告。

收集數據
使用如 stat memory、memreport、記憶體洞察等工具,或使用 UE 以外的分析工具來調查記憶體使用情況:
- 永遠在真實設備或打包版本中進行調查。
- 在 PIE 模式下,預加載的緩存和背景操作可能會影響測量,使準確結果變得困難。
 
 - 記憶體使用情況會因設備而異。
 
檢查總記憶體使用情況
要檢查整體記憶體使用情況,最好確保至少有 500MB 的物理記憶體可用。
使用 memreport -full 進行檢查:
- Memreport 的一部分: 顯示總體記憶體使用情況。
- 在轉儲文件中搜尋 "Physical Memory" 來找到此資訊。

 
 - 在轉儲文件中搜尋 "Physical Memory" 來找到此資訊。
 
檢查材質記憶體使用情況
你可以通過顯示 listtextures nonvt 報告(按大小排序)來檢查材質的記憶體使用情況。
使用 memreport -full 進行檢查:
- Memreport 的一部分: 顯示按記憶體使用量降序排列的材質。
- 在轉儲文件中搜尋 "listtextures" 來找到此資訊。

 
 - 在轉儲文件中搜尋 "listtextures" 來找到此資訊。
 
分析數據
識別高記憶體使用的資源 (如材質)。
調查不必要或過大資源
要調查是否加載了不必要的資源:
使用命令 obj list name= 根據名稱搜尋資源並檢查它是否已經加載。
範例: obj list name=T_SomeTexture
使用命令 obj refs name= 顯示哪些物件正在參考給定的資源,幫助你識別為什麼它會被加載。
範例: obj refs name=T_SomeTexture
此外,你可以使用參考查看器進一步追蹤參考的來源,並調查硬參考是如何被創建的。
有關硬參考和軟參考的更多信息:
提出改進措施
- 刪除不必要的資源
 - 使用低解析度的紋理
 - 合併或壓縮大文件
 
實施改進措施
修正有問題的資源或防止其被加載。
- 刪除不必要的資源:
- 移除硬參考。
 
 - 釋放不再使用的資源:
- 將硬參考轉為軟參考,並在應該釋放時將其設置為 
nullptr,這樣它們會在下一次垃圾回收時被釋放。 
 - 將硬參考轉為軟參考,並在應該釋放時將其設置為 
 - 使用低解析度的紋理或調整壓縮設置。
 - 根據需要進行其他調整。
 
驗證
通過 memreport 比較優化前後的內存使用情況。
如何檢查有問題的資源是否不再加載
可以使用 gc.ForceCollectGarbageEveryFrame 1 或 obj gc 強制進行垃圾回收。
當資源不再被引用(對於軟參考設置 nullptr)時,可以強制進行垃圾回收。然後,使用 obj list name= 檢查資源是否仍然加載。如果它仍然加載,則意味著仍有引用,您應該再次進行數據分析。
比較內存使用變化
使用 memreport -full 或 memreport -log 指令來檢查整體內存使用情況,並比較優化或調整前後的差異。
內存優化的關鍵要點
- 培養防止內存洩漏的習慣,確保資源能夠正確釋放。
 - 小心硬參考,它們可能會加載所有引用的對象。
 - 適當使用軟參考。
 - 持續監控內存使用情況,以進行改進。
 
總結
- 內存優化的重要性
旨在提高性能、縮短加載時間,並防止內存崩潰。 - 有用的命令和工具
stat memorymemreport -log、memreport -fullobj list、obj refs name=obj gc、gc.ForceCollectGarbageEveryFrame- LLM
 - 參考查看器
 - 尺寸地圖
 - 內存洞察工具
 
 - 優化過程
識別問題、收集數據、分析、提出改進、實施修復並驗證。 
優化措施範例
- 刪除不必要的資源或防止其被加載
 - 使用低解析度的紋理或調整壓縮設置
 - 根據數據分析進行其他調整
 
希望本文能在您遇到內存不足導致崩潰時提供幫助。
如果有任何錯誤,請在評論中告訴我,我會進行修正。
參考資料
- Qiita: 使用 Memreport 調查內存洩漏原因 (ja)
 - Ari's Unreal Engine Notes: 調試內存洩漏
 - [UE4] 使用 Memreport 有效分析內存 (ja)
 - [UE4] 使用 Obj 指令進行對象分析 (ja)
 - 官方文檔:在 Unreal Engine 中處理對象 (ja)
 - 【UE5】強制執行垃圾回收操作 (ja)
 - 【UE4】關於 UObject 的 PendingKill | HEXADRIVE (ja)
 - 官方文檔:Low-Level Memory Tracker (ja)
 - [UE4] 使用 LLM 進行內存跟蹤 (ja)
 - 官方文檔:Unreal Engine 中的參考查看器 (en)
 - 視頻:如何優化 Unreal Engine 5 遊戲中的內存使用
 - Qiita: 使用 UE4 內存洞察工具進行內存跟蹤 (ja)
 - 官方文檔:Unreal Engine 中的內存洞察工具
 - 視頻:在 Unreal Engine 中最大化遊戲性能 | Unreal Fest 2022
 - 硬參考和軟參考 (ja)
 - 如何打破 BP 參考鏈 (ja)
 - 紋理格式 (ja)
 - [UE5] 圖像壓縮格式 (ja)
 - 視頻:如何在 Unreal Engine 5 中優化移動端的紋理
 - 調試和內存優化 (ja)
 - UE5 中的基礎 Mipmap 設置 (ja)